package com.papercutting.platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.papercutting.platform.dto.request.TutorialStepRequest;
import com.papercutting.platform.dto.response.TutorialStepResponse;
import com.papercutting.platform.entity.Tutorial;
import com.papercutting.platform.entity.TutorialStep;
import com.papercutting.platform.repository.TutorialRepository;
import com.papercutting.platform.repository.TutorialStepRepository;
import com.papercutting.platform.service.TutorialStepService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 教程步骤服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TutorialStepServiceImpl implements TutorialStepService {

    private final TutorialStepRepository tutorialStepRepository;
    private final TutorialRepository tutorialRepository;
    
    @Override
    public TutorialStep save(TutorialStep tutorialStep) {
        if (tutorialStep.getId() == null) {
            tutorialStepRepository.insert(tutorialStep);
        } else {
            tutorialStepRepository.updateById(tutorialStep);
        }
        return tutorialStep;
    }

    @Override
    public TutorialStep findById(Long id) {
        return tutorialStepRepository.selectById(id);
    }

    @Override
    public List<TutorialStep> findAll() {
        return tutorialStepRepository.selectList(null);
    }

    @Override
    public void deleteById(Long id) {
        tutorialStepRepository.deleteById(id);
    }

    @Override
    public List<TutorialStep> findByTutorialId(Long tutorialId) {
        LambdaQueryWrapper<TutorialStep> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TutorialStep::getTutorialId, tutorialId)
               .eq(TutorialStep::getDeleted, false);
        return tutorialStepRepository.selectList(wrapper);
    }

    @Override
    public List<TutorialStep> findByTutorialIdOrderByStepNumberAsc(Long tutorialId) {
        LambdaQueryWrapper<TutorialStep> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TutorialStep::getTutorialId, tutorialId)
               .eq(TutorialStep::getDeleted, false)
               .orderByAsc(TutorialStep::getStepNumber);
        return tutorialStepRepository.selectList(wrapper);
    }

    @Override
    public TutorialStep findByTutorialIdAndStepNumber(Long tutorialId, Integer stepNumber) {
        LambdaQueryWrapper<TutorialStep> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TutorialStep::getTutorialId, tutorialId)
               .eq(TutorialStep::getStepNumber, stepNumber)
               .eq(TutorialStep::getDeleted, false);
        return tutorialStepRepository.selectOne(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createStep(TutorialStepRequest request) {
        log.info("创建教程步骤: 教程ID={}, 步骤={}", request.getTutorialId(), request.getStepNumber());

        // 验证教程是否存在
        Tutorial tutorial = tutorialRepository.selectById(request.getTutorialId());
        if (tutorial == null) {
            throw new RuntimeException("教程不存在");
        }

        // 创建步骤实体
        TutorialStep step = new TutorialStep();
        BeanUtils.copyProperties(request, step);
        step.setCreateTime(LocalDateTime.now());
        step.setUpdateTime(LocalDateTime.now());
        step.setDeleted(false);

        // 保存步骤
        tutorialStepRepository.insert(step);

        // 更新教程的步骤数量
        updateTutorialStepsCount(request.getTutorialId());

        log.info("教程步骤创建成功，ID: {}", step.getId());
        return step.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStep(TutorialStepRequest request) {
        log.info("更新教程步骤: {}", request.getId());

        // 查找现有步骤
        TutorialStep step = tutorialStepRepository.selectById(request.getId());
        if (step == null) {
            throw new RuntimeException("教程步骤不存在");
        }

        // 更新步骤信息
        BeanUtils.copyProperties(request, step, "id", "createTime");
        step.setUpdateTime(LocalDateTime.now());

        // 保存更新
        tutorialStepRepository.updateById(step);

        log.info("教程步骤更新成功: {}", request.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteStep(Long id) {
        log.info("删除教程步骤: {}", id);

        // 查找步骤
        TutorialStep step = tutorialStepRepository.selectById(id);
        if (step == null) {
            throw new RuntimeException("教程步骤不存在");
        }

        Long tutorialId = step.getTutorialId();

        // 使用MyBatis Plus的逻辑删除
        tutorialStepRepository.deleteById(id);

        // 更新教程的步骤数量
        updateTutorialStepsCount(tutorialId);

        log.info("教程步骤删除成功: {}", id);
    }

    @Override
    public TutorialStepResponse getStepById(Long id) {
        log.info("获取教程步骤详情: {}", id);

        TutorialStep step = tutorialStepRepository.selectById(id);
        if (step == null) {
            throw new RuntimeException("教程步骤不存在");
        }

        return convertToResponse(step);
    }

    @Override
    public List<TutorialStepResponse> getStepsByTutorialId(Long tutorialId) {
        log.info("获取教程步骤列表: 教程ID={}", tutorialId);

        LambdaQueryWrapper<TutorialStep> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TutorialStep::getTutorialId, tutorialId)
               .eq(TutorialStep::getDeleted, false)
               .orderByAsc(TutorialStep::getStepNumber);
        List<TutorialStep> steps = tutorialStepRepository.selectList(wrapper);

        return steps.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchCreateSteps(List<TutorialStepRequest> requests) {
        log.info("批量创建教程步骤: 数量={}", requests.size());

        if (requests.isEmpty()) {
            return;
        }

        Long tutorialId = requests.get(0).getTutorialId();

        // 验证教程是否存在
        Tutorial tutorial = tutorialRepository.selectById(tutorialId);
        if (tutorial == null) {
            throw new RuntimeException("教程不存在");
        }

        // 批量创建步骤
        List<TutorialStep> steps = requests.stream()
                .map(request -> {
                    TutorialStep step = new TutorialStep();
                    BeanUtils.copyProperties(request, step);
                    step.setCreateTime(LocalDateTime.now());
                    step.setUpdateTime(LocalDateTime.now());
                    step.setDeleted(false);
                    return step;
                })
                .collect(Collectors.toList());

        steps.forEach(step -> tutorialStepRepository.insert(step));

        // 更新教程的步骤数量
        updateTutorialStepsCount(tutorialId);

        log.info("批量创建教程步骤成功: 数量={}", steps.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reorderSteps(Long tutorialId, List<Long> stepIds) {
        log.info("重新排序教程步骤: 教程ID={}", tutorialId);

        for (int i = 0; i < stepIds.size(); i++) {
            Long stepId = stepIds.get(i);
            TutorialStep step = tutorialStepRepository.selectById(stepId);
            if (step == null) {
                throw new RuntimeException("教程步骤不存在: " + stepId);
            }

            step.setStepNumber(i + 1);
            step.setSortOrder(i);
            step.setUpdateTime(LocalDateTime.now());
            tutorialStepRepository.updateById(step);
        }

        log.info("教程步骤重新排序成功");
    }

    /**
     * 更新教程的步骤数量
     */
    private void updateTutorialStepsCount(Long tutorialId) {
        LambdaQueryWrapper<TutorialStep> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TutorialStep::getTutorialId, tutorialId)
               .eq(TutorialStep::getDeleted, false);
        List<TutorialStep> steps = tutorialStepRepository.selectList(wrapper);

        Tutorial tutorial = tutorialRepository.selectById(tutorialId);
        if (tutorial == null) {
            throw new RuntimeException("教程不存在");
        }

        tutorial.setStepsCount(steps.size());
        tutorial.setUpdateTime(LocalDateTime.now());
        tutorialRepository.updateById(tutorial);
    }

    // ========== 管理员API方法实现 ==========

    @Override
    public List<TutorialStepResponse> getTutorialSteps(Long tutorialId) {
        return getStepsByTutorialId(tutorialId);
    }

    @Override
    public TutorialStepResponse getTutorialStepById(Long id) {
        return getStepById(id);
    }

    @Override
    @Transactional
    public Long createTutorialStep(TutorialStepRequest request) {
        return createStep(request);
    }

    @Override
    @Transactional
    public void updateTutorialStep(TutorialStepRequest request) {
        updateStep(request);
    }

    @Override
    @Transactional
    public void deleteTutorialStep(Long id) {
        deleteStep(id);
    }

    @Override
    @Transactional
    public void batchCreateTutorialSteps(List<TutorialStepRequest> requests) {
        batchCreateSteps(requests);
    }

    @Override
    @Transactional
    public void reorderTutorialSteps(Long tutorialId, List<Long> stepIds) {
        reorderSteps(tutorialId, stepIds);
    }

    /**
     * 转换步骤实体为响应对象
     */
    private TutorialStepResponse convertToResponse(TutorialStep step) {
        TutorialStepResponse response = new TutorialStepResponse();
        BeanUtils.copyProperties(step, response);
        return response;
    }
}